package com.deep.transaction.demo5.service.impl;


import com.deep.transaction.demo5.dao.User2Dao;
import com.deep.transaction.demo5.service.User2Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;


/*
存在问题：
业务层主要功能：转账、增删改查
业务层辅助功能：开启事务、提交事务、回滚事务

优化：
将辅助功能抽取出来，作为事务工具类

如果该方法只做查询，可以设置readOnly = true，提高效率
readOnly = true 只能设置在读操作上，否则会报错：
Connection is read-only. Queries leading to data modification are not allowed;

timeout = 3:
设置超时回滚，超过三秒就回滚

rollbackFor = Exception.class:
设置遇到异常就回滚，不管是编译异常还是说是运行异常

noRollbackFor = ArithmeticException.class：
设置遇到算术异常不回滚

事务的隔离级别：
隔离级别：
    1.READ UNCOMMITTED : 读未提交
        存在问题：脏读 ,不可重复读, 幻读
    2.READ COMMITTED : 读已提交
        存在问题：不可重复读, 幻读
    3.REPEATABLE READ : 可重复读
        存在问题：幻读
    4.SERIALIZABLE : 串行化
        存在问题：效率低

    脏读：一个事务可以读取到另一个事务中未提交的数据

    不可重复读：一个事务多次读取另一个事务中的同一个数据,前后不一致

    幻读：一个事务查询一条记录显示没有,该事务添加这条记录又显示有

事务的隔离级别如果不设置的话，默认是可重复读
 */
@Transactional(readOnly = true)
@Service("user2ServiceImpl")
public class User2ServiceImpl implements User2Service {
    @Autowired
    private User2Dao user2Dao;

    @Transactional(readOnly = false, timeout = 3, rollbackFor = Exception.class,
            isolation = Isolation.REPEATABLE_READ, noRollbackFor = ArithmeticException.class)
    public void transfer(String outName, String inName, Integer money) throws Exception {

        //出账
        user2Dao.outMoney(outName, money);

        System.out.println(1 / 0);

        //入账
        user2Dao.inMoney(inName, money);

    }
}
